﻿using System;
using System.IO;
using UtilZ.Dotnet.Ex.Model;

namespace UtilZ.Dotnet.Ex.Communication.Net.BMQ
{
    /// <summary>
    /// BMQ二进制消息
    /// </summary>
    public class BMQBlobMessage : BMQDataMessageAbs
    {

        private readonly DataSpan<byte> _data = new DataSpan<byte>();
        /// <summary>
        /// 二进制内容
        /// </summary>
        public DataSpan<byte> Data
        {
            get { return _data; }
        }


        /// <summary>
        /// 构造函数-解析
        /// </summary>
        public BMQBlobMessage()
            : base(BMQMessageTypes.BlobMessage)
        {

        }


        /// <summary>
        /// 构造函数-创建
        /// </summary>
        /// <param name="topic">订阅主题</param>
        /// <param name="data">二进制内容</param>
        public BMQBlobMessage(short topic, byte[] data)
            : base(BMQMessageTypes.BlobMessage, topic)
        {
            this._data.Update(data);
        }

        /// <summary>
        /// 构造函数-创建
        /// </summary>
        /// <param name="topic">订阅主题</param>
        public BMQBlobMessage(short topic)
            : base(BMQMessageTypes.BlobMessage, topic)
        {

        }


        /// <summary>
        /// 获取消息大小
        /// </summary>
        /// <returns>消息大小</returns>
        protected override int GetMessageSize()
        {
            if (this._data == null)
            {
                return BMQ_DATA_HEADER_SIZE;
            }

            return BMQ_DATA_HEADER_SIZE + this._data.Length;
        }


        /// <summary>
        /// 写消息内容到BinaryWriter
        /// </summary>
        /// <param name="writer">消息写器</param>
        protected override void WriteContent(BinaryWriter writer)
        {
            if (this._data.DataType == DataSpanDataType.DataPtr)
            {
#if NET4_0
                for (int i = 0; i < this._data.Length; i++)
                {
                    writer.Write(this._data[i]);
                }
#else
                writer.Write(this._data.GetSpan());
#endif
            }
            else
            {
                writer.Write(this._data.Array, this._data.Offset, this._data.Length);
            }
        }

        /// <summary>
        /// 读取消息内容
        /// </summary>
        /// <param name="reader">内容二进制数据</param>
        /// <param name="dataLength">数据字节数</param>
        protected override void ReadContent(BinaryReader reader, int dataLength)
        {
            if (this._data.Array == null || this._data.Array.Length < dataLength)
            {
                byte[] data = reader.ReadBytes(dataLength);
                this._data.Update(data, 0, dataLength);
            }
            else
            {
                reader.Read(this._data.Array, 0, dataLength);
                this._data.Update(0, dataLength);
            }
        }

    }
}
